<template>
    <el-button
        v-bind="$attrs"
        :class="computedClass"
        :size="computedSize"
        :style="{ overflow: $attrs.loading ? 'visible' : 'hidden' }"
        :type="type === 'second' ? '' : type"
        class="button"
        @click="click"
    >
        <slot />
        <div
            v-if="ripple"
            :class="[waveActive ? 'wave-active' : '']"
            :style="{
                top: rippleTop + 'px',
                left: rippleLeft + 'px',
                width: fields.targetWidth + 'px',
                height: fields.targetWidth + 'px',
                'background-color': rippleBgColor || 'rgba(0, 0, 0, 0.15)'
            }"
            class="wave-ripple"
        />
    </el-button>
</template>

<script>
import throttle from '@/utils/throttle'

export default {
    name: 'BaseButton',
    props: {
        // 默认为small，本规范只支持small和mini两种大小按钮
        size: {
            type: String,
            default: 'small'
        },
        // 默认为primary主要蓝色按钮，次要的为second白色按钮，文字按钮为text，本规范只支持这三种类型按钮
        type: {
            type: String,
            default: 'primary'
        },
        color: {
            type: String,
            default: ''
        },
        // 水波纹的背景颜色
        rippleBgColor: {
            type: String,
            default: ''
        },
        // 是否开启水波纹效果
        ripple: {
            type: Boolean,
            default: true
        },
        // 节流，一定时间内只能触发一次
        throttleTime: {
            type: [String, Number],
            default: 500
        }
    },
    data() {
        return {
            rippleTop: 0, // 水波纹的起点Y坐标到按钮上边界的距离
            rippleLeft: 0, // 水波纹起点X坐标到按钮左边界的距离
            fields: {}, // 波纹按钮节点信息
            waveActive: false // 激活水波纹
        }
    },
    computed: {
        computedSize() {
            if (this.type === 'text') {
                return ''
            }
            return this.size
        },
        computedClass() {
            let className = ''
            if (this.color) {
                className = 'button--text--' + this.color
            }
            if (this.type === 'second') {
                className += 'button-second'
            }
            return className
        }
    },
    methods: {
        click(e) {
            throttle(() => {
                // 如果按钮时disabled和loading状态，不触发水波纹效果
                if (this.$attrs.loading === true || this.$attrs.disabled === true) {
                    return
                }
                // 是否开启水波纹效果
                if (this.type !== 'text' && this.ripple) {
                    // 每次点击时，移除上一次的类，再次添加，才能触发动画效果
                    this.waveActive = false
                    this.$nextTick(() => {
                        this.getWaveQuery(e)
                    })
                }
                this.$emit('click', e)
            }, this.throttleTime)
        },
        // 查询按钮的节点信息
        getWaveQuery(e) {
            const data = e.target.getBoundingClientRect()
            // 查询不到节点信息，不操作
            if (!data.width || !data.height) return
            // 水波纹的最终形态是一个正方形(通过border-radius让其变为一个圆形)，这里要保证正方形的边长等于按钮的最长边
            // 最终的方形（变换后的圆形）才能覆盖整个按钮
            data.targetWidth = data.height > data.width ? data.height : data.width
            if (!data.targetWidth) return
            this.fields = data

            // 获取触摸点相对于按钮上边和左边的x和y坐标
            // 但是由于`transform-origin`默认是center，所以这里再减去半径才是水波纹view应该的位置
            // 总的来说，就是把水波纹的矩形（变换后的圆形）的中心点，移动到我们的触摸点位置
            this.rippleTop = e.pageY - data.top - data.targetWidth / 2 - document.documentElement.scrollTop || document.body.scrollTop
            this.rippleLeft = e.pageX - data.left - data.targetWidth / 2 - document.documentElement.scrollLeft || document.body.scrollLeft
            this.$nextTick(() => {
                this.waveActive = true
            })
        }
    }
}
</script>
<style lang="scss">
// el-button默认样式覆盖
.el-button {
    &:focus {
        outline: none;
    }
    &.is-loading {
        overflow: hidden !important;
        opacity: 0.5;
        background: #0062ff;
        border-color: #0062ff;
    }
    &.el-button--small {
        min-width: 94px;
    }

    &.el-button--mini {
        min-width: 62px;
    }

    &:hover {
        color: #44444f;
        border-color: #0062ff;
        background-color: #fff;
    }

    &:focus {
        color: #0062ff;
        border-color: #0062ff;
        background-color: rgba(0, 98, 255, 0.15);
    }
}

.el-button + .el-button {
    margin-left: 8px;
}

// 这里是为了解决表格里使用v-show显示隐藏按钮时边距不一致问题
table {
    .el-button + .el-button {
        margin-left: 0;
    }
    .el-button {
        margin-right: 8px;
    }
}
// button自定义样式，配合水波纹
.button {
    position: relative;

    span {
        pointer-events: none;
    }

    &:active {
        opacity: 1;
    }
}

// 水波纹样式
.wave-ripple {
    z-index: 0;
    position: absolute;
    border-radius: 100%;
    background-clip: padding-box;
    pointer-events: none;
    user-select: none;
    transform: scale(0);
    opacity: 1;
    transform-origin: center;
}

.wave-ripple.wave-active {
    opacity: 0;
    transform: scale(2);
    transition: opacity 1s linear, transform 0.4s linear;
}

// 默认样式覆盖
.el-button.el-button--primary {
    color: #fff;
}

.el-button.is-disabled,
.el-button.is-disabled:focus,
.el-button.is-disabled:hover {
    background-color: #fff;
}

.el-button--primary:focus,
.el-button--primary:hover {
    background: #2166dd;
    border-color: #2166dd;
    color: #fff;
}

.el-button--primary.is-disabled,
.el-button--primary.is-disabled:active,
.el-button--primary.is-disabled:focus,
.el-button--primary.is-disabled:hover {
    opacity: 0.5;
    background: #0062ff;
    border-color: #0062ff;
    color: #fff;
}

.el-button--text {
    padding: 8px 0;
    min-width: 0;
}

.el-button--text:focus,
.el-button--text:hover {
    color: #2961dd;
    border-color: transparent;
    background-color: transparent;
}

.el-button--text.is-disabled,
.el-button--text.is-disabled:active,
.el-button--text.is-disabled:focus,
.el-button--text.is-disabled:hover {
    color: #0062ff;
    opacity: 0.5;
}

.button-second.is-loading {
    background-color: #fff;
    border-color: #e2e2e2;
}

// 文字按钮增加color配置，分别为danger红色、success绿色、warning黄色
.button--text--danger {
    color: #e50834;

    &:hover,
    &:focus,
    &:active {
        color: #d0072f;
    }
}

.button--text--danger.is-disabled,
.button--text--danger.is-disabled:active,
.button--text--danger.is-disabled:focus,
.button--text--danger.is-disabled:hover {
    opacity: 0.5;
    color: #e50834;
}

.button--text--success {
    color: #61d291;

    &:hover,
    &:focus,
    &:active {
        color: #58be83;
    }
}

.button--text--success.is-disabled,
.button--text--success.is-disabled:active,
.button--text--success.is-disabled:focus,
.button--text--success.is-disabled:hover {
    opacity: 0.6;
    color: #61d291;
}

.button--text--warning {
    color: #eaac3f;

    &:hover,
    &:focus,
    &:active {
        color: #e1a53c;
    }
}

.button--text--warning.is-disabled,
.button--text--warning.is-disabled:active,
.button--text--warning.is-disabled:focus,
.button--text--warning.is-disabled:hover {
    opacity: 0.65;
    color: #eaac3f;
}

.el-button--primary.is-plain {
    color: #0062ff;
}
</style>
